#include <stdio.h>
#include <pthread.h>
#include <time.h>
#include "../../src/stack/tagged_stack.h"

#define NUM_THREADS 4
#define OPS_PER_THREAD 1000000
#define DELAY_CYCLES 100  // 用于模拟ABA问题的延迟

tagged_stack_t stack;
atomic_int push_count = 0;
atomic_int pop_count = 0;

// 添加延迟以增加ABA问题发生的可能性
static inline void add_delay() {
    for (int i = 0; i < DELAY_CYCLES; i++) {
        cpu_pause();
    }
}

void* worker(void* arg) {
    int thread_id = *(int*)arg;
    
    for (int i = 0; i < OPS_PER_THREAD; i++) {
        if (i % 2 == 0) {
            // Push操作
            int* value = malloc(sizeof(int));
            *value = i;
            if (tagged_stack_push(&stack, value)) {
                atomic_fetch_add(&push_count, 1, memory_order_relaxed);
            }
            add_delay();  // 增加延迟
        } else {
            // Pop操作
            void* data = tagged_stack_pop(&stack);
            if (data) {
                free(data);
                atomic_fetch_add(&pop_count, 1, memory_order_relaxed);
            }
            add_delay();  // 增加延迟
        }
    }
    return NULL;
}

int main() {
    pthread_t threads[NUM_THREADS];
    int thread_ids[NUM_THREADS];
    struct timespec start, end;
    
    tagged_stack_init(&stack);
    clock_gettime(CLOCK_MONOTONIC, &start);
    
    // 创建线程
    for (int i = 0; i < NUM_THREADS; i++) {
        thread_ids[i] = i;
        pthread_create(&threads[i], NULL, worker, &thread_ids[i]);
    }
    
    // 等待所有线程完成
    for (int i = 0; i < NUM_THREADS; i++) {
        pthread_join(threads[i], NULL);
    }
    
    clock_gettime(CLOCK_MONOTONIC, &end);
    
    double time_spent = (end.tv_sec - start.tv_sec) +
                       (end.tv_nsec - start.tv_nsec) / 1e9;
    
    printf("Time spent: %.2f seconds\n", time_spent);
    printf("Operations per second: %.2f\n", 
           (NUM_THREADS * OPS_PER_THREAD) / time_spent);
    printf("Total pushes: %d\n", atomic_load(&push_count, memory_order_relaxed));
    printf("Total pops: %d\n", atomic_load(&pop_count, memory_order_relaxed));
    
    // 清理剩余的节点
    while (!tagged_stack_is_empty(&stack)) {
        void* data = tagged_stack_pop(&stack);
        if (data) free(data);
    }
    
    return 0;
} 